package com.loozb.thread3;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 演示使用tryLock让线程不进入死锁
 * @author 龙召碧
 * @create 2018-01-30 17:17
 **/
public class TryLock implements Runnable {
    public static ReentrantLock lock1 = new ReentrantLock();
    public static ReentrantLock lock2 = new ReentrantLock();
    int lock;
    public TryLock(int lock) {
        this.lock = lock;
    }

    @Override
    public void run() {
        if(lock == 1) {
            while (true) {
                //循环，直到获取到锁
                if(lock1.tryLock()) {
                    try {
                        try {
                            //模拟业务操作500MS
                            System.out.println("实际业务操作1");
                            Thread.sleep(500);
                        } catch (InterruptedException e) {
                        }

                        if (lock2.tryLock()) {
                            //lock1获取锁业务操作结束后，获取另外一个锁
                            try {
                                System.out.println(Thread.currentThread().getId() + ":My Job done");
                                return;
                            } finally {
                                lock2.unlock();
                            }
                        }
                    } finally {
                        lock1.unlock();
                    }
                }
            }
        } else {
            while (true) {
                //循环，直到获取到锁
                if(lock2.tryLock()) {
                    try {
                        try {
                            //模拟业务操作500MS
                            System.out.println("实际业务操作2");
                            Thread.sleep(500);
                        } catch (InterruptedException e) {
                        }

                        if (lock1.tryLock()) {
                            //lock1获取锁业务操作结束后，获取另外一个锁
                            try {
                                System.out.println(Thread.currentThread().getId() + ":My Job done");
                                return;
                            } finally {
                                lock1.unlock();
                            }
                        }
                    } finally {
                        lock2.unlock();
                    }
                }
            }
        }
    }

    /**
     * 如果使用new AccountingVol()，则上锁需要用静态static
     * @param args
     * @throws InterruptedException
     */
    public static void main(String[] args) throws InterruptedException {
        TryLock r1 = new TryLock(1);
        TryLock r2 = new TryLock(2);
        Thread t1 = new Thread(r1);
        Thread t2 = new Thread(r2);
        t1.start();
        t2.start();
    }
}
